﻿#ifndef __ESTREE_VISITOR_H__
#define __ESTREE_VISITOR_H__

#include "cpp-gen/JsonVisitor.h"
#include "configurable_visitor.hpp"

namespace cyclone::parser
{
    class DummyNode;
    class EstreeVisitor : public JsonVisitor, public ConfigurableVisitor
    {
        template <class T>
        auto processTypeAnnotationInPattern(T *ctx, Json &res)
        {
            if (ctx->typeAnnotation_)
                res["typeAnnotation"] = dispatch(ctx->typeAnnotation_);
            return res;
        }
        template <class T>
        auto processTypeAnnotationInPattern(T *ctx)
        {
            IF_NULLPTR_RETURN_DEFAULT(ctx);
            auto jsonifyNode = JsonVisitor::visit(ctx);
            processTypeAnnotationInPattern(ctx, jsonifyNode);
            return jsonifyNode;
        }
        bool isOptionalCallChain(FormalParser::ExpressionContext *ctx);
        std::set<FormalParser::ExpressionContext *> optionalCallChainAncestors_;

    public:
        Json visit(FormalParser::MemberExpressionContext *ctx);
        Json visit(FormalParser::CallExpressionContext *ctx);
        Json visit(FormalParser::IdentifierExpressionContext *ctx);
        Json visit(FormalParser::DotMemberExpressionContext *ctx);
        Json visit(FormalParser::BracketMemberExpressionContext *ctx);
        Json visit(FormalParser::UnaryExpressionContext *ctx);
        Json visit(FormalParser::UpdateExpressionContext *ctx);
        Json visit(FormalParser::SourceElementContext *ctx);
        Json visit(FormalParser::ProgramContext *ctx);
        Json visit(FormalParser::FunctionDeclarationContext *ctx);
        Json visit(FormalParser::FunctionExpressionContext *ctx);
        Json visit(FormalParser::ArrowFunctionExpressionContext *ctx);
        Json visit(FormalParser::YieldExpressionContext *ctx);
        Json visit(FormalParser::PrivateMemberExpressionContext *ctx);
        Json visit(FormalParser::PrivateIdentifierContext *ctx);
        Json visit(FormalParser::ExpressionSequenceContext *ctx);
        Json visit(FormalParser::LiteralExpressionContext *ctx);
        Json visit(FormalParser::LiteralContext *ctx);
        Json visit(FormalParser::ThisExpressionContext *ctx);
        Json visit(FormalParser::TemplateLiteralContext *ctx);
        Json visit(FormalParser::ClassExpressionContext *ctx);
        Json visit(FormalParser::PropertyShorthandContext *ctx);
        Json visit(FormalParser::ShorthandAssignmentPropertyContext *ctx);
        Json visit(FormalParser::VariableDeclaratorContext *ctx);
        Json visit(FormalParser::MetaPropertyIdentifierContext *ctx);
        Json visit(FormalParser::ReturnStatementContext *ctx);
        Json visit(FormalParser::ParenthesizedExpressionContext *ctx);
        Json visit(FormalParser::LogicalExpressionContext *ctx);
        Json visit(FormalParser::IdentifierContext *ctx);
        Json visit(FormalParser::ObjectPatternContext *ctx);
        Json visit(FormalParser::ArrayPatternContext *ctx);
        Json visit(FormalParser::RestElementContext *ctx);

        Json visit(DummyNode *ctx);

        // Type
        Json visit(FormalParser::PrimitiveTypeContext *ctx) override;
        Json visit(FormalParser::TupleTypeContext *ctx) override;
    };

} // namespace cyclone::parser

#endif // __ESTREE_VISITOR_H__